cc.Class({
    extends: cc.Component,
    properties: {
        /** 金币动画启动 */
        startNode: cc.Node,
        /** 金币动画终点 */
        endNode: cc.Node,
        /** 金币数值Label */
        coinNumLabel: cc.Label,
        /** 金币预制节点 */
        coinPrefab: cc.Prefab,
        /** 金币节点池 */
        coinPool: null,
        /** 金币数 */
        coinNum: 1000
    },


    onLoad() {
        this.coinPool = new cc.NodePool();
        this.coinNumLabel.string = this.coinNum.toString();
        this.initCoinPool();
    },
    /** 先预先创建几个节点放入节点池中 */
    initCoinPool(count = 20) {
        for (let i = 0; i < count; i++) {
            let coin = cc.instantiate(this.coinPrefab);
            this.coinPool.put(coin);
        }
    },

    /** 从节点池中取出节点 */
    getCoinNode() {
        let coin = null;
        if (this.coinPool.size() > 0) {
            coin = this.coinPool.get();
        } else {
            coin = cc.instantiate(this.coinPrefab);
        }
        return coin;
    },

    playAnim() {
        let randomCount = Math.random() * 10 + 10;
        let stPos = this.startNode.convertToWorldSpaceAR(this.startNode.getPosition());
        let edPos = this.endNode.convertToWorldSpaceAR(this.endNode.getPosition())
        this.playCoinRewardAnim(randomCount, stPos, edPos);
        this.node.getComponent('SoundManager').playAudio()
    },

    /**
     * 金币飞向钱包的动画
     *
     * @param {number} count 金币数量
     * @param {cc.Vec2} stPos 金币起始位置
     * @param {cc.Vec2} edPos 金币终点位置
     * @param {number} [r=130] 金币飞行的半径
     */
    playCoinRewardAnim(count, stPos, edPos, r = 130) {
        // 生成圆，并且对圆上的点进行排序
        stPos = this.node.convertToNodeSpaceAR(stPos)
        edPos = this.node.convertToNodeSpaceAR(edPos)
        let points = this.getCirclePosition(r, stPos, count);
        let coinNodeList = points.map(pos => {
            let coin = this.getCoinNode();
            coin.setPosition(stPos);
            this.node.addChild(coin);
            return {
                node: coin,
                stPos: stPos,
                mdPos: pos,
                edPos: edPos,
                dis: pos.sub(edPos).mag()
            };
        });
        coinNodeList = coinNodeList.sort((a, b) => a.dis - b.dis);
        // 执行金币落袋的动画
        coinNodeList.forEach((item, idx) => {
            cc.tween(item.node)
                .to(0.3, {
                    position: item.mdPos
                })
                .delay(idx * 0.01)
                .to(0.5, {
                    position: item.edPos
                })
                .call(() => {
                    // 金币落袋后，将金币节点放入节点池中，并更新金币数值
                    this.coinNum += 20;
                    this.coinNumLabel.string = this.coinNum.toString();
                    this.coinPool.put(item.node);
                })
                .start();
        });
    },

    /**
     * 以某点为圆心，生成圆周上等分点的坐标
     * @param {number} radius 半径
     * @param {cc.Vec2} pos 圆心坐标
     * @param {number} count 等分点数量
     * @param {number} randomScope 等分点的随机波动范围
     * @returns {cc.Vec2[]} 返回等分点坐标
     */
    getCirclePosition(radius, pos, count, randomScope = 60) {
        let positions = [];
        let radians = (Math.PI / 180) * Math.round(360 / count);
        for (let i = 0; i < count; i++) {
            let x = pos.x + radius * Math.sin(radians * i);
            let y = pos.y + radius * Math.cos(radians * i);
            positions.unshift(cc.v3(x + Math.random() * randomScope, y + Math.random() * randomScope, 0));
        }
        return positions;
    }
})